home *** CD-ROM | disk | FTP | other *** search
- ; Listing 3 - STKDEV2.ASM
- ;** PC-DOS Device Driver - Reconfigurable Stack for Structures ( 1-32K bytes)
- ;
- ; Bruce Bordner, 1985
- ;
- ;
- CSEG SEGMENT PARA PUBLIC 'CODE'
- ;
- yell macro char
- push es
- push di
- push ax
- mov ax,'&char'
- les di,CS:bugout
- stos byte ptr [di]
- inc di
- mov word ptr CS:bugout,di
- pop ax
- pop di
- pop es
- endm
- ;
- XSTK PROC FAR
- ASSUME CS:CSEG,DS:CSEG,ES:CSEG
- BEGIN:
- START EQU $
- ; Header for DOS Device Drivers
- NEXT_DEV DD -1 ; fake pointer to next device driver
- ATTRIBUTE DW 0C000H ;character device with IOCTL capability
- STRATEGY DW XSTK_STRAT ;pointer to function which queues request header
- FUNC_CALL DW XSTK_FUNC ;pointer to operating functions switch
- DEV_NAME DB 'XSTK ' ;8-byte device name field
- ;
- ; Pointer to function request from DOS
- RH_OFF DW ?
- RH_SEG DW ?
- ;
- ; Function Address Table for DOS Requests
- FUNTAB LABEL BYTE
- DW INIT ; initialize device
- DW MEDIA_CHECK ; do a media check (block dev only)
- DW BUILD_BPB ; build BPB " " "
- DW IOCTL_IN ; IOCTL input
- DW INPUT ; normal input (read device)
- DW ND_INPUT ; non-destructive input no wait
- DW IN_STAT ; report input status
- DW IN_FLUSH ; flush input
- DW OUTPUT ; output (write to device)
- DW OUT_VERIFY ; output with verify
- DW OUT_STAT ; report output status
- DW OUT_FLUSH ; flush output
- DW IOCTL_OUT ; IOCTL output
- ;
- bugout dd 0B8000000h ; screen address for yell macro
- ;
- ; Internal Data
- BOTMEM DW ? ; start of stack storage space
- TOPMEM DW ? ; end of storage (BOTMEM + 32K)
- RECSIZE DW ? ; size of each structure to store, in bytes
- CURRENT DW ? ; address after current "top of stack" - free spot
- NUM2READ DW 0 ; number of bytes left to read to make full recsize
- NUM2WRITE DW 0 ; number left to write
- ; *end local data
- ;
- ;
- ;
- ; Device Strategy - set pointer to request header from DOS
- XSTK_STRAT: MOV CS:RH_SEG,ES
- MOV CS:RH_OFF,BX
- RET
- ;
- ; Device Interrupt Handler
- XSTK_FUNC: ;preserve machine state
- PUSHF
- CLD
- PUSH DS
- PUSH ES
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH DI
- PUSH SI
- ; Set DS to CS value
- PUSH CS
- POP DS
- ; Load ES and BX with RH_SEG and RH_OFF
- LES BX,DWORD PTR CS:RH_OFF
- ; Branch to correct function in FUNTAB based on function code from DOS
- MOV AL,ES:[BX+2] ; get function code byte
- XOR AH,AH
- SHL AL,1 ; make it into offset into FUNTAB
- LEA DI,FUNTAB ; get address of FUNTAB base
- ADD DI,AX
- JMP WORD PTR[DI] ; jump to function code
- ;
- ;
- ;
- ; Functions not supported:
- ;
- MEDIA_CHECK:
- BUILD_BPB:
- ND_INPUT:
- OUT_VERIFY:
- MOV ES:WORD PTR [BX+3],0100H ; set status DONE, NOERROR
- JMP EXIT
- ;************************************************************
- ;
- ; Device Initialization
- INIT: MOV AX,OFFSET STORAGE
- MOV BOTMEM,AX ; set lower limit
- MOV CURRENT,AX ; set current record address
- ADD AX,32768 ; add 32K for top limit
- MOV TOPMEM,AX
- MOV ES:[BX+14],AX ; return end of XSTK space
- MOV ES:[BX+16],CS ; and segment into request hdr
- MOV RECSIZE,1 ; default recsize = 1 byte
- MOV WORD PTR ES:[BX+3],0100H ;set status word to DONE, NOERROR
- JMP EXIT
- ;
- ;************************************************************
- ;
- INPUT: ; report record size
- MOV CX,WORD PTR ES:[BX+18] ; get #bytes requested
- LEA SI,RECSIZE
- LES DI,DWORD PTR ES:[BX+14]
- REP MOVSB
- LES BX,DWORD PTR CS:RH_OFF
- MOV ES:WORD PTR [BX+3],0100H ; set status DONE, NOERROR
- JMP EXIT
- ;************************************************************
- OUTPUT: ; change record size
- MOV CX,WORD PTR ES:[BX+18]
- LEA DI,RECSIZE
- PUSH DS
- LDS SI,DWORD PTR ES:[BX+14]
- POP ES
- REP MOVSB
- LES BX,DWORD PTR CS:RH_OFF
- MOV ES:WORD PTR [BX+3],0100H ; set status DONE, NOERROR
- JMP EXIT
- ;************************************************************
- ;
- IN_STAT:
- OUT_STAT: ; BUSY if any records stacked, DONE if empty?
- MOV ES:WORD PTR [BX+3],0100H ; set status DONE, NOERROR
- JMP EXIT
- ;************************************************************
- ;
- IN_FLUSH:
- OUT_FLUSH: ; empty stack
- MOV ES:WORD PTR [BX+3],0100H ; set status DONE, NOERROR
- JMP EXIT
- ;************************************************************
- ; Primary I/O Functions
- ;
- ; ES:[BX]+14 = offset of buffer in calling program
- ; ES:[BX]+16 = segment of buffer
- ; ES:[BX]+18 = size of buffer
- ;
- ;
- ;
- IOCTL_IN: ; pop record from stack to calling program's buffer
- yell R
- MOV SI,CURRENT ; set SI to next byte position
- SUB SI,RECSIZE ; sub record size from CURRENT
- CMP SI,BOTMEM ; make sure full record can be pulled
- JGE PULLIT
- MOV WORD PTR ES:[BX+3],8130H ; else error 30H, stack empty
- MOV WORD PTR ES:[BX+18],0 ; no bytes transferred
- yell e
- JMP EXIT
- PULLIT: MOV CX,WORD PTR ES:[BX+18] ; #bytes to move
- MOV DI,WORD PTR ES:[BX+14] ; get buffer offset + seg
- MOV AX,WORD PTR ES:[BX+16]
- MOV ES,AX
- MOV CS:CURRENT,SI ; SI points to beginning of rec
- REP MOVSB ; copy record to program buffer from stack at SI
- LES BX,DWORD PTR CS:RH_OFF ; reset to DOS request header
- MOV WORD PTR ES:[BX+3],0100H ; set DONE, NOERROR
- JMP EXIT
- ;*************************************************************
- ;
- IOCTL_OUT: ; push record from calling program buffer onto stack storage
- yell W
- MOV DI,CURRENT ; set DI to next byte position
- MOV DX,DI
- ADD DX,RECSIZE ; add record size to CURRENT
- CMP TOPMEM,DX ; make sure full record can be stored
- JNG STUFFIT
- MOV WORD PTR ES:[BX+3],8120H ; else error 20H, stack full
- MOV WORD PTR ES:[BX+18],0 ; no bytes transferred
- yell f
- JMP EXIT
- STUFFIT: MOV CX,WORD PTR ES:[BX+18] ; #bytes to move
- PUSH DS ; need this for ES later
- LDS SI,DWORD PTR ES:[BX+14] ; get buffer offset + seg
- POP ES ; set to old DS value to reference stack space
- REP MOVSB ; copy record from program buffer to stack at DI
- MOV CS:CURRENT,DX ; use DX to set current at next rec
- LES BX,DWORD PTR CS:RH_OFF ; reset to DOS request header
- MOV WORD PTR ES:[BX+3],0100H ; set DONE, NOERROR
- JMP EXIT
- ;*********************************************************
- ;
- ; Restore registers and exit
- EXIT: POP SI
- POP DI
- POP DX
- POP CX
- POP BX
- POP AX
- POP ES
- POP DS
- POPF
- RET
- ;
- ;
- ; Align stack storage to start on a paragraph boundary - fits all storage types
- if ($-START) MOD 16
- ORG ($-START)+16-(($-START) MOD 16)
- endif
- ;
- STORAGE EQU $ ; start of stack storage space
- ;
- XSTK ENDP
- CSEG ENDS
- END BEGIN
- T)+16-(($-START) MOD 16)
- endif
- ;
- STORAGE EQU $ ; start o